package com.framework.config;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import com.bdt.SampleBdt;
import com.framework.interceptor.CorsInterceptor;

/**
 * MVC 설정용 클래스. 이 클래스는 스프링의 sevlet-context.xml 의 역할을 대신한다. 인터셉터를 추가하기 위해
 * WebMvcConfigurationSupport를 상속한다.
 */
@Configuration
@ComponentScan(basePackages = "com"
	, useDefaultFilters = false
	, includeFilters = {
		@ComponentScan.Filter(Controller.class)
		,@ComponentScan.Filter(Service.class)
		, @ComponentScan.Filter(Repository.class)
		, @ComponentScan.Filter(Component.class)
		}
	, excludeFilters = {
		@ComponentScan.Filter(Configuration.class)
	}
)
@EnableAspectJAutoProxy(proxyTargetClass = true)
//@PropertySource("/WEB-INF/application.properties")
public class WebMvcConfig extends WebMvcConfigurationSupport {

	@Inject Environment env;

	/**
	 * 인터셉터 추가
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new CorsInterceptor());
	}

	/**
	 * DefaultServletHandling 맵핑이 없을 경우 : <mvc:default-servlet-handler />
	 */
	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	@Override
	protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		converters.add(this.jsonConverter());
		converters.add(this.xmlConverter());
		converters.add(this.ByteArrayConverter());
		super.configureMessageConverters(converters);
	}

	@Override
	protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		configurer
		.favorPathExtension(true)
		.ignoreAcceptHeader(true)
		.useJaf(false)
		.defaultContentType(MediaType.TEXT_HTML)
		.mediaType("json", MediaType.APPLICATION_JSON)
		.mediaType("xml", MediaType.APPLICATION_XML)
		;
	}

	/**
	 * Json Converter
	 *
	 * @return
	 */
	private MappingJackson2HttpMessageConverter jsonConverter(){
		MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
		List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
		supportedMediaTypes.add(MediaType.APPLICATION_JSON);
		jsonConverter.setPrettyPrint(true);
		jsonConverter.setSupportedMediaTypes(supportedMediaTypes);
		return jsonConverter;
	}

	/**
	 * Xml Converter
	 *
	 * @return
	 */
	private MarshallingHttpMessageConverter xmlConverter(){
		Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
		marshaller.setClassesToBeBound(SampleBdt.class);
		marshaller.setCheckForXmlRootElement(true);
		MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(marshaller);
		List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
		supportedMediaTypes.add(MediaType.APPLICATION_XML);
		xmlConverter.setSupportedMediaTypes(supportedMediaTypes);
		return xmlConverter;
	}

	/**
	 * Image Converter
	 *
	 * @return
	 */
	private ByteArrayHttpMessageConverter ByteArrayConverter() {
		ByteArrayHttpMessageConverter converter = new ByteArrayHttpMessageConverter();
		List<MediaType> mediatype = new ArrayList<MediaType>();
		mediatype.add(MediaType.IMAGE_PNG);
		mediatype.add(MediaType.IMAGE_JPEG);
		mediatype.add(MediaType.IMAGE_GIF);
		converter.setSupportedMediaTypes(mediatype);
		return converter;
	}
}
